// 蜂窝蜜造平台生成代码，如手工更改，请添加到 .beeignore 忽略生成

package com.fowo.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.*;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fowo.api.common.annotaion.DataObjectType;
import com.fowo.api.datainterface.util.JsonUtil;
import com.fowo.api.entity.AmazonFinancialEventGroup;
import com.fowo.api.model.amazon.financial.event.group.*;
import com.fowo.api.model.bd.rate.BdRateSelectBdRateDetailParam;
import com.fowo.api.model.bd.rate.BdRateSelectBdRateDetailResult;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 亚马逊结算中心-交易汇总 服务实现类
 *
 * @author 蜂窝蜜造平台 配置人：任凯
 */
@Service
@Slf4j
@DataObjectType(AmazonFinancialEventGroup.class)
@DS("ds24")
public class AmazonFinancialEventGroupServiceImpl extends AmazonFinancialEventGroupBaseServiceImpl {

    @Resource
    private BdRateServiceImpl bdRateService;

    @Resource
    private AmazonSettlementReportServiceImpl amazonSettlementReportService;

    @Override
    public Page<AmazonFinancialEventGroupItemVo> pageSearch(AmazonFinancialEventGroupSearchParamPo search) {
        final List<String> currencyTypeInList = search.getOriginalTotalCurrencyCodeInList();
        search.setOriginalTotalCurrencyCodeInList(null);
        return this.translatRate(CollUtil.getFirst(currencyTypeInList), super.pageSearch(search));
    }

    /**
     * 根据币种转换汇率
     *
     * @param currency
     * @param page
     * @return
     */
    private Page<AmazonFinancialEventGroupItemVo> translatRate(String currency, Page<AmazonFinancialEventGroupItemVo> page) {
        if (CollUtil.isEmpty(page.getRecords())) {
            return page;
        }
        //处理展开数据
        AmazonFinancialEventGroupSelectGroupAttachInfoParam attachInfoParam = new AmazonFinancialEventGroupSelectGroupAttachInfoParam();
        attachInfoParam.setFinancialEventGroupId(page.getRecords().stream().map(AmazonFinancialEventGroupItemVo::getFinancialEventGroupId).collect(Collectors.toList()));
        List<AmazonFinancialEventGroupSelectGroupAttachInfoResult> attachInfoResultList = this.selectGroupAttachInfo(attachInfoParam);
        if (CollUtil.isEmpty(attachInfoResultList)) {
            return page;
        }
        for (AmazonFinancialEventGroupItemVo item : page.getRecords()) {
            BigDecimal ratio = BigDecimal.ONE;
            if (StrUtil.isNotBlank(currency)) {
                BdRateSelectBdRateDetailParam rateDetailParam = new BdRateSelectBdRateDetailParam();
                rateDetailParam.setFromcurrency(item.getOriginalTotalCurrencyCode());
                rateDetailParam.setTocurrency(currency);
                rateDetailParam.setDate(DateUtil.format(item.getSettlementStartDate(), DatePattern.NORM_MONTH_PATTERN));
                BdRateSelectBdRateDetailResult rate = bdRateService.selectBdRateDetail(rateDetailParam);
                if (ObjUtil.isEmpty(rate)) {
                    continue;
                }
                ratio = Convert.toBigDecimal(rate.getRatio()); //转换汇率
                item.setOriginalTotalCurrencyCode(rate.getTocurrency()); //转换币种
            }
            this.attachInfoCalculator(attachInfoResultList, item, ratio);
        }
        return page;
    }

    /**
     * 计算展开信息
     *
     * @param attachInfoList
     * @param item
     * @return
     */
    private void attachInfoCalculator(List<AmazonFinancialEventGroupSelectGroupAttachInfoResult> attachInfoList, AmazonFinancialEventGroupItemVo item, BigDecimal ratio) {
        if (CollUtil.isEmpty(attachInfoList)) {
            return;
        }
        item.setTransferConvertedTotalCurrencyAmount(this.getAmount(attachInfoList, "应收金额", ratio)); //应收金额
        item.setTransferBeginningBalanceCurrencyAmount(this.getAmount(attachInfoList, "期初余额", ratio)); //期初余额
        item.setTransferOriginalTotalCurrencyAmount(this.getAmount(attachInfoList, "本期结算", ratio)); //本期结算
        item.setTransferPreviousReserveAmount(this.getAmount(attachInfoList, "预留退回", ratio)); //预留退回
        item.setTransferCurrentReserveAmount(this.getAmount(attachInfoList, "本期预留", ratio)); //本期预留
        item.setTransferCreditCardDeduction(this.getAmount(attachInfoList, "信用卡扣款", ratio)); //信用卡扣款

        item.setSale(this.getAmount(attachInfoList, "收入", ratio)); //收入
        item.setSaleProduct(this.getAmount(attachInfoList, "产品销售", ratio)); //产品销售
        item.setSaleFreight(this.getAmount(attachInfoList, "买家运费", ratio)); //买家运费
        item.setSalePacking(this.getAmount(attachInfoList, "包装", ratio)); //包装
        item.setSaleOther(this.getAmount(attachInfoList, "其他", ratio)); //其他
        item.setSaleTax(this.getAmount(attachInfoList, "税", ratio)); //税

        item.setRefund(this.getAmount(attachInfoList, "退款", ratio));   //退款
        item.setRefundSaleRefund(this.getAmount(attachInfoList, "收入退款", ratio)); //收入退款
        item.setRefundFeeRefund(this.getAmount(attachInfoList, "费用退款", ratio));   //费用退款
        item.setRefundTax(this.getAmount(attachInfoList, "税退款", ratio));    //税退款

        item.setPay(this.getAmount(attachInfoList, "支出", ratio));     //支出
        item.setPayStorage(this.getAmount(attachInfoList, "仓储费用", ratio));  //仓储费用
        item.setPayAmazon(this.getAmount(attachInfoList, "亚马逊费用", ratio));    //亚马逊费用
        item.setPayAd(this.getAmount(attachInfoList, "广告费", ratio));      //广告费
        item.setPayPromotion(this.getAmount(attachInfoList, "促销费", ratio));   //促销费
        item.setPayOther(this.getAmount(attachInfoList, "其他", ratio));   //其他

        //回款率=转账金额/收入
        if (NumberUtil.equals(item.getCollectionRate(), BigDecimal.ZERO)) {
            item.setCollectionRate(NumberUtil.mul(NumberUtil.div(item.getConvertedTotal(), item.getSale()), 100));
        }
    }

    /**
     * 获取费用
     *
     * @param attachInfoResultList
     * @param type
     * @return
     */
    private BigDecimal getAmount(List<AmazonFinancialEventGroupSelectGroupAttachInfoResult> attachInfoResultList, String type, BigDecimal ratio) {
        final AmazonFinancialEventGroupSelectGroupAttachInfoResult attachInfo = CollUtil.findOne(attachInfoResultList, f -> StrUtil.equals(f.getType(), type));
        return ObjUtil.isEmpty(attachInfo) ? BigDecimal.ZERO : NumberUtil.mul(attachInfo.getAmount(), ratio);
    }

    /**
     * 手工入账
     *
     * @param ids
     * @param type 未到账 已到账
     * @throws Exception
     */
    public void manualReceipt(List<Long> ids, String type) throws Exception {
        Assert.isTrue(CollUtil.isNotEmpty(ids), "参数异常!");
        try {
            this.update(
                    Wrappers.<AmazonFinancialEventGroup>lambdaUpdate()
                            .set(AmazonFinancialEventGroup::getFundTransferGetStatus, type)
                            .in(AmazonFinancialEventGroup::getId, ids)
            );
        } catch (Exception ex) {
            log.error("发生异常,异常信息:" + StrUtil.subPre(ExceptionUtil.getRootCauseMessage(ex), 2000));
            throw new RuntimeException("发生异常,信息:" + StrUtil.subPre(ExceptionUtil.getRootCauseMessage(ex), 2000));
        }
    }

}





